﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Data;
using System.ComponentModel;
using System.Threading;
using System.Security.Principal;

namespace OWANotifier
{
    public class OWAMessageListRequest
    {

        public string X509CertificateFilename { get; set; }

        public Uri Uri { get; set; }

        public string User { get; set; }

        public bool IntegratedSecurity { get; set; }

        public string Password { get; set; }

        public OWAMessageListRequest()
        {

        }


        public IList<Message> Request()
        {
            DataSet ds = null;

            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(Uri);

            if (!string.IsNullOrEmpty(X509CertificateFilename))
            {
                X509Certificate cert = new X509Certificate(X509CertificateFilename);
                req.ClientCertificates.Add(cert);
            }

            req.PreAuthenticate = true;

            if (IntegratedSecurity)
            {
                req.Credentials = CredentialCache.DefaultCredentials;
                req.UseDefaultCredentials = true;
            }
            else
            {
                req.Credentials = new NetworkCredential(GetUser(User), Password, GetDomain(User));
            }
            req.CookieContainer = new CookieContainer();

            string contents;
            try
            {

                using (WebResponse resp = req.GetResponse())
                {
                    using (StreamReader rdr = new StreamReader(resp.GetResponseStream()))
                        contents = rdr.ReadToEnd();
                }

                int start, length;

                //start = contents.IndexOf("<BODY ");
                //length = contents.LastIndexOf("</BODY>") + 7 - start;
                //contents = contents.Substring(start, length);

                start = contents.IndexOf("\r\n\r\n<TABLE");
                length = contents.IndexOf("</TABLE>", start + 1) + 8 - start;
                contents = contents.Substring(start, length);

                ds = HtmlTableParser.TableToDataSet(contents, false);

                DataTable mt = ds.Tables[0];
                mt.Columns[0].ColumnName = "Link";
                mt.Columns[1].ColumnName = "Importance";
                mt.Columns[2].ColumnName = "Status";
                mt.Columns[3].ColumnName = "Flag";
                mt.Columns[4].ColumnName = "Attachments";

                foreach (DataRow dr in mt.Rows)
                {
                    if (dr[2].ToString().Contains("msg-unread"))
                        dr[2] = "unread";
                    else
                        dr[2] = "";

                    if (dr[1].ToString().Contains("imp-high"))
                        dr[1] = "high";
                    else
                        dr[1] = "";

                    if (dr[4].ToString().Contains("paperclip"))
                        dr[4] = "attachments";
                    else
                        dr[4] = "";


                    Regex hrefRE = new Regex("href=\\\"Inbox/.*Cmd=open\\\"");
                    if (hrefRE.Match(dr[6].ToString()).Success)
                    {
                        dr[0] = hrefRE.Match(dr[6].ToString()).Value.Substring("href=".Length).Trim('"');

                        dr[0] = new Uri(Uri, "..\\" + dr[0].ToString()).ToString();

                    }


                    for (int i = 0; i < dr.ItemArray.Length; i++)
                    {
                        dr[i] = HtmlTableParser.ParsePlainText(dr[i].ToString());
                    }
                }


                return new BindingList<Message>(
                    mt.AsEnumerable().Select(dr => new Message
                    {
                        Unread = (dr["Status"].ToString() == "unread"),
                        HasAttachments = (dr["Attachments"].ToString() == "attachments"),
                        From = dr["From"].ToString(),
                        Subject = dr["Subject"].ToString(),
                        Importance = dr["Importance"].ToString(),
                        Received = DateTime.Parse(dr["Received"].ToString()),
                        Size = dr["Size"].ToString(),
                        Url = dr["Link"].ToString()
                    }).OrderByDescending(m => m.Received).ToList());

            }
            catch (Exception)
            {
                throw;
            }

        }


        public static string GetUser(string domainUsername)
        {
            if (domainUsername.Contains('\\'))
                return domainUsername.Split('\\')[1];
            else
                return domainUsername;
        }

        public static string GetDomain(string domainUsername)
        {
            if (domainUsername.Contains('\\'))
                return domainUsername.Split('\\')[0];
            else
                return "";
        }

    }
}
